package com.nstar.base.container
{
	/**
	 * @name		: MagicCanvas
	 * @description : A magic canvas,a canvas with background image or gradient color.
	 * 				  image layout is tile, center or stretch.
	 * 				  gradient color can be any color,rotation default is PI/2.
	 * @author		: zhuchuanming@gmail.com
	 * @date		: 2010.03
	 */ 
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.GradientType;
	import flash.display.Graphics;
	import flash.display.SpreadMethod;
	import flash.geom.Matrix;
	import flash.geom.Point;
	
	import mx.containers.Canvas;
	import mx.core.Container;
	import mx.events.FlexEvent;

	public class MagicCanvas extends Canvas
	{
		//layout
		public static const LAYOUT_TILE:String = "tile";
		public static const LAYOUT_CENTER:String = "center";
		public static const LAYOUT_STRETCH:String = "stretch";
		//background type
		public static const TYPE_IMAGE:String = "image";
		public static const TYPE_COLOR:String = "color";
		
		private var _source:DisplayObject;//a image component
		private var _layout:String  = LAYOUT_TILE;//default is tile
		private var _backgroundType:String = TYPE_IMAGE;//default is image
		private var _rotationDegree:Number = Math.PI/2;//default is 90
		
		//If use gradient color, you can use color1 and color2 properties
		private var color1:uint = 0xFFFFFF;
		private var color2:uint = 0xFFFFFF;
		
		public function MagicCanvas()
		{
			super();
			this.addEventListener(FlexEvent.CREATION_COMPLETE,init);
		}
		
		private function init(event:FlexEvent):void{
			
		}
		
		//source,a image object,use this image to draw background
		public function set source(value:DisplayObject):void{
			this._source = value;
			drawBackground(this._source,this,_layout);
		}
		
		public function get source():DisplayObject{
			return this._source;
		}
		
		//set layout
		public function set layout(value:String):void{
			this._layout = value;
		}
		
		public function get layout():String{
			return this._layout;
		}	
		
		//backround type,image or color,const is TYPE_IMAGE/TYPE_COLOR
		public function set backgroundType(value:String):void{
			this._backgroundType = value;
		}
		
		public function get backgroundType():String{
			return this._backgroundType;
		}
		
		//if backround is gradient, this paramter can set gradient color rotation.
		public function set rotationDegree(value:Number):void{
			this._rotationDegree = value;
		}
		
		public function get rotationDegree():Number{
			return this._rotationDegree;
		}		

	    //draw background with image
	    private function drawBackground(source:DisplayObject,
	    	dest:Container,layout:String=LAYOUT_TILE):void{
	    	this.backgroundType = TYPE_IMAGE;
	    	dest.graphics.clear();
	    	//get image active width and height
	    	var cw:Number = Object(source).contentWidth;
	    	var ch:Number = Object(source).contentHeight;
	    	var bd:BitmapData = new BitmapData(cw,ch);
	    	bd.draw(source,new Matrix());
	    	var matrix:Matrix = new Matrix();
	    	
	    	switch(layout){
	    		case LAYOUT_TILE://draw tile background
	    			dest.graphics.beginBitmapFill(bd,matrix);
	    			dest.graphics.drawRect(0,0,dest.width,dest.height);
	    			break;
	    		case LAYOUT_CENTER://draw image center
			    	var p:Point = new Point();
			    	p.x = (dest.width-cw)/2;
			    	p.y = (dest.height - ch)/2;	  
			    	matrix.translate(p.x,p.y);  		
	    			dest.graphics.beginBitmapFill(bd,matrix);
	    			dest.graphics.drawRect(p.x,p.y,cw,ch);
	    			break;
	    		case LAYOUT_STRETCH://stretch image to fit background
	    			matrix.scale(dest.width/cw,dest.height/ch);
			    	dest.graphics.beginBitmapFill(bd,matrix,false);
			    	dest.graphics.drawRect(0,0,dest.width,dest.height);	    			
	    			break;
	    	}
	    	dest.graphics.endFill();
	    }
	    
	    //draw a gradient rectangle,from color1 to color2.
		public function drawGradientBackground(color1:uint = 0x346bac,
			color2:uint = 0x34b5f9,rotation:Number=Math.PI/2):void{
			this.color1 = color1;
			this.color2 = color2;
			this.rotationDegree = rotation;
			
			this.backgroundType = TYPE_COLOR;
			var g:Graphics = this.graphics;
			g.clear();
			var matrix:Matrix=new Matrix(); 
			matrix.createGradientBox(this.width,this.height,rotation,0,0); 
			var spreadMethod:String = SpreadMethod.PAD;
			//set default parameters
			var alphas:Array=[1,1]; 
			var ratios:Array=[0,255]; 
			var colors:Array = [color1,color2];
			//draw gradient background
			g.beginGradientFill(GradientType.LINEAR,colors,alphas,ratios,matrix,spreadMethod);        
			g.drawRect(0,0,this.width,this.height); 
			g.endFill();  			
		}
	    
	    //if change IE Browser size,than redraw it 
	    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
	    	super.updateDisplayList(unscaledWidth,unscaledHeight);
	    	if(_source){
	    		switch(backgroundType){
	    			case TYPE_IMAGE:
	    				drawBackground(_source,this,_layout);//redraw bacground with image
	    				break;
	    			case TYPE_COLOR:
	    				drawGradientBackground(color1,color2,rotationDegree);//redraw gradient color background
	    				break;
	    		}
	    		
	    	}
	    }
	}
}